package top.aiprogram.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
//如果通过配置的方式新建切点则不能用注解的方式

//新建切面
@Component //为了能让spring扫描到，添加一个组件，不知道是干嘛的所以添加component
@Aspect //声明切面
public class UserAspect {
    //切点，告诉spring容器我要在哪个地方切入，要拦截那个方法
    @Pointcut(value = "execution(* top.aiprogram.service.*.*(..))") //value中装的是个正则表达式，首先先打一个*，然后路径，service.*是service下所有方法，继续.*就是下面的方法(..)代表所有方法
    public void pointCut(){ }

    //advice  通知   我要干的事情  什么时候干
    //拦截了方法之前要干什么
    @Before(value = "pointCut()")
    public void doBecore(JoinPoint joinPoint){//JoinPoint 连接点 程序执行的点  具体执行的是某个方法
        String name = joinPoint.getSignature().getName(); //拿到连接点的方法的名称
        Object[] args =  joinPoint.getArgs();
        System.out.println("连接点方法名称："+name);
        for(int i = 0 ; i<args.length ; i++){
            System.out.println("参数为："+args[i]);
        }
    }

    //拦截了方法之后要干什么
    @After(value = "pointCut()")
    public void doAfter(JoinPoint joinPoint){
        String name = joinPoint.getSignature().getName();
        System.out.println("连接点方法名称："+name+"   ");
    }


    //可以拿到这个方法的返回值
    @AfterReturning(value = "pointCut()",returning = "result") //返回的是result
    public void afterReturning(JoinPoint joinPoint, Object result){
        System.out.println("返回值为："+result);
    }


    //抛异常时会干什么
    @AfterThrowing
    public void afterThrowing(){

    }


    //环绕通知，控制方法的执行，全程监控方法的运行
    @Around(value = "pointCut()")
    public void around(ProceedingJoinPoint proceedingJoinPoint){ //推进连接点，继续执行
        try {
            proceedingJoinPoint.proceed();//一定要执行此方法，否则则会卡死，不会执行连接点方法，拦截住了
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }

    }
}
